package gui;

import java.util.ArrayList;
import java.util.List;

import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Cursor;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Line;
import javafx.scene.shape.Shape;
import listener.PieceHandlerMouseDragging;
import listener.PieceHandlerMouseDropped;
import listener.PieceHandlerMouseEntered;
import listener.PieceHandlerMouseExit;
import logic.ChessGame;
import logic.IPlayerHandler;
import logic.Log;
import logic.Move;
import logic.Piece;

public class ChessGUI extends AnchorPane implements IPlayerHandler {

	ChessGame chessGame;
	private List<Shape> markPoints;
	private List<PieceGUI> pieces;
	private PieceGUI dragPiece;

	private Move lastMove;
	private Move currentMove;

	private boolean dragginGamePiecesEnabled;

	public ChessGUI(ChessGame chessGame) {
		this.chessGame = chessGame;
		this.markPoints = new ArrayList<Shape>();
		this.pieces = new ArrayList<PieceGUI>();
		initComponent();

	}

	public void resetPiecesByCoor() {
		for (PieceGUI p : this.pieces) {
			p.setLayoutX(10 + (p.getX() * 50));
			p.setLayoutY(10 + (p.getY() * 50));
			if (p.getPiece().isCaptured()) {
				this.getChildren().remove(p);
			}
		}
	}

	public void resetPieces() {
		Platform.runLater(new Runnable() {

			@Override
			public void run() {
				for (PieceGUI p : pieces) {
					p.setLayoutX(10 + (p.getPiece().getColumn() * 50));
					p.setLayoutY(10 + (p.getPiece().getRow() * 50));
					if (p.getPiece().isCaptured()) {
						getChildren().remove(p);
					}
				}
			}
		});
	}

	public void setCurrentMove(Move move) {
		this.currentMove = move;
	}

	public void addMarkPoint(Shape s) {
		this.markPoints.add(s);
		this.getChildren().add(s);
	}

	public void removeAllMarkPoints() {
		for (Shape s : markPoints) {
			this.getChildren().remove(s);
		}
		this.markPoints.clear();
	}

	public void setChessGame(ChessGame chessGame) {
		this.chessGame = chessGame;
	}

	private void initComponent() {
		this.setPadding(new Insets(0, 40, 40, 0));
		int x = 30;
		for (int i = 0; i < 10; i++) {
			Label row = new Label("" + (i + 1));
			row.setLayoutX(15);
			row.setLayoutY(x);
			this.getChildren().add(row);
			this.getChildren().add(new Line(30, x, 430, x));
			x += 50;
		}

		int y = 30;
		for (int i = 0; i < 9; i++) {
			this.getChildren().add(new Line(y, 30, y, 230));
			this.getChildren().add(new Line(y, 280, y, 480));
			y += 50;
		}

		this.getChildren().add(new Line(30, 230, 30, 280));
		this.getChildren().add(new Line(430, 230, 430, 280));

		this.getChildren().add(new Line(180, 30, 280, 130));
		this.getChildren().add(new Line(180, 130, 280, 30));

		this.getChildren().add(new Line(180, 380, 280, 480));
		this.getChildren().add(new Line(180, 480, 280, 380));
		addPiece();
	}

	private void addPiece() {
		for (Piece p : chessGame.getPieces()) {
			PieceGUI b = new PieceGUI(p);
			// double ox = b.getLayoutX(), oy = b.getLayoutY();
			// System.out.println(ox);
			// System.out.println(oy);
			b.setOnMouseDragged(new PieceHandlerMouseDragging(b, this));
			b.setOnMouseEntered(new PieceHandlerMouseEntered(this, b));
			b.setOnMouseExited(new PieceHandlerMouseExit(b, chessGame, this));
			b.setOnMouseReleased(new PieceHandlerMouseDropped(this, b));
			this.pieces.add(b);
			this.getChildren().add(b);
		}
	}

	public ChessGame getChessGame() {
		return chessGame;
	}

	@Override
	public Move getMove() {
		this.dragginGamePiecesEnabled = true;
		Move moveForExecution = this.currentMove;
		this.currentMove = null;
		if (moveForExecution != null)
			System.out.println("get move: " + moveForExecution);
		return moveForExecution;
	}

	private PieceGUI getPieceGUIAt(int row, int col) {
		for (PieceGUI p : this.pieces) {
			if (p.getX() == col && p.getY() == row
					&& p.getPiece().isCaptured() == false) {
				return p;
			}
		}
		return null;
	}

	@Override
	public void moveSuccessfullyExecuted(Move move) {
		PieceGUI p = this.getPieceGUIAt(move.getTargetRow(),
				move.getTargetColumn());
		if (p == null) {
			// throw new IllegalStateException("no pieceGUI at " +
			// move.targetRow
			// + "/" + move.targetColumn);
		} else {

			p.getPiece().setColumn(move.getTargetColumn());
			p.getPiece().setRow(move.getTargetRow());
			this.lastMove = move;

			this.dragginGamePiecesEnabled = false;
		}
		this.resetPieces();
	}

	public String toString() {
		return this.chessGame.showGameState();
	}

	public Move getCurrentMove() {
		return this.currentMove;
	}

	public void showMarkPoints() {
		for (Shape s : markPoints) {
			s.setVisible(true);
		}
	}
}
